# apps/tags/views.py
from django.db.models import F
from rest_framework import viewsets, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django_filters import rest_framework as django_filters
from django_filters import FilterSet, CharFilter

from .models import Tag
from .serializers import (
    TagSerializer,
    TagCreateUpdateSerializer,
    TagListSerializer,
    TagDetailSerializer
)
from ..common.mixins import TenantViewSetMixin


# =================== 过滤器 ===================
class TagFilter(FilterSet):
    """
    标签过滤器，支持按名称、分类进行模糊查询
    """
    name = CharFilter(field_name='name', lookup_expr='icontains', help_text="标签名称模糊查询")
    category = CharFilter(field_name='category', lookup_expr='icontains', help_text="分类模糊查询")
    exact_category = CharFilter(field_name='category', lookup_expr='exact', help_text="精确匹配分类")

    class Meta:
        model = Tag
        fields = ['name', 'category', 'exact_category']


# =================== 主视图集 ===================
class TagViewSet(TenantViewSetMixin, viewsets.ModelViewSet):
    """
    标签管理视图集
    提供标签的增删改查接口
    """

    queryset = Tag.objects.all().order_by('-created_at')
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_class = TagFilter
    search_fields = ['name', 'description']
    ordering_fields = ['created_at', 'updated_at', 'used_count', 'name']
    ordering = ['-created_at']

    def get_serializer_class(self):
        """
        根据不同动作使用不同的序列化器
        """
        if self.action == 'list':
            return TagListSerializer
        elif self.action == 'retrieve':
            return TagDetailSerializer
        elif self.action in ['create', 'update', 'partial_update']:
            return TagCreateUpdateSerializer
        return TagSerializer

    def get_serializer_context(self):
        """
        传递上下文（如 request）给序列化器
        """
        context = super().get_serializer_context()
        context.update({"request": self.request})
        return context

    def create(self, request, *args, **kwargs):
        """
        重写 create 方法，支持返回更详细的响应
        """
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        instance = serializer.save()

        # 返回完整详情
        detail_serializer = TagDetailSerializer(instance, context=self.get_serializer_context())
        return Response(detail_serializer.data, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        """
        重写 update 方法，支持返回完整数据
        """
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        instance = serializer.save()

        detail_serializer = TagDetailSerializer(instance, context=self.get_serializer_context())
        return Response(detail_serializer.data, status=status.HTTP_200_OK)

    # =================== 自定义动作 ===================
    @action(detail=False, methods=['get'], url_path='categories', url_name='categories')
    def list_categories(self, request):
        """
        获取所有唯一的标签分类（category）
        GET /tags/categories/
        """
        categories = Tag.objects.filter(category__isnull=False).values_list('category', flat=True).distinct().order_by('category')
        return Response({
            'count': len(categories),
            'results': list(categories)
        })

    @action(detail=False, methods=['get'], url_path='by-category/(?P<category>[^/.]+)', url_name='by-category')
    def list_by_category(self, request, category=None):
        """
        按分类获取标签列表
        GET /tags/by-category/知识点/
        """
        tags = Tag.objects.filter(category=category).order_by('name')
        if not tags.exists():
            return Response({'detail': '该分类下无标签。'}, status=status.HTTP_404_NOT_FOUND)

        page = self.paginate_queryset(tags)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(tags, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=['post'], url_path='increment', url_name='increment')
    def increment_used_count(self, request, pk=None):
        tag = self.get_object()
        # 原子递增
        Tag.objects.filter(pk=tag.pk).update(used_count=F('used_count') + 1)
        tag.refresh_from_db()  # 重新读取数据
        serializer = TagDetailSerializer(tag, context=self.get_serializer_context())
        return Response(serializer.data)